import logging
from entity.database.mysql import Conversation, Message, TestSuite, TestCase, FileRecord
from utils.createID_tool import ConversationIdGenerator


async def create_conversation_in_db():
    """
    创建新对话
    :return: 是否创建成功
    """
    # 使用推荐的缩短UUID方案
    conversation_id = ConversationIdGenerator.generate_short_uuid()

    # 检查ID是否已存在（极低概率冲突处理）
    while await Conversation.exists(conversation_id=conversation_id):
        logging.warning(f"ID冲突: {conversation_id}，重新生成")
        conversation_id = ConversationIdGenerator.generate_short_uuid()

    # 创建对话记录
    await Conversation.create(
        conversation_id=conversation_id,
        title="新对话"
    )
    return {"chatId": conversation_id}

async def get_conversations_in_db():
    """
    获取对话列表信息。
    :return:
    """
    # 查询最近更新的10条对话（按更新时间倒序）
    conversations = await (((Conversation.all()
                           .order_by("-update_time"))
                           .limit(10))
                           .values("conversation_id", "title"))
    # 转换为接口要求的格式
    return [
        {
            "chatId": conv["conversation_id"],
            "chatTitle": conv["title"]
        }
        for conv in conversations
    ]

async def get_messages_in_db(conversationId:str):
    """
    获取对话中的历史记录
    :param conversationId: 对话id
    :return: 对话中的所有信息。
    """

    # 辅助函数：格式化文件大小
    def format_file_size(size_bytes: float) -> str:
        """
        将字节大小转换为更友好的格式 (KB, MB)
        :param size_bytes: 文件大小（字节）
        :return: 格式化后的文件大小字符串
        """
        # 如果大小无效，返回空字符串
        if size_bytes is None:
            return ""

        # 转换为MB（大于1MB）
        if size_bytes >= 1024 * 1024:
            return f"{size_bytes / (1024 * 1024):.2f} MB"
        # 转换为KB（大于1KB）
        elif size_bytes >= 1024:
            return f"{size_bytes / 1024:.2f} KB"
        # 小于1KB直接显示字节
        else:
            return f"{size_bytes:.0f} B"

    # 1. 获取基础消息列表（按创建时间排序）
    messages = await Message.filter(conversation_id=conversationId) \
        .order_by("created_time") \
        .values(
        "message_id",
        "content",
        "message_source"
    )

    # 2. 处理AI消息（message_source=1）
    ai_message_ids = [msg["message_id"] for msg in messages if msg["message_source"] == 1]
    # 收集用户消息ID用于文件查询
    user_message_ids = [msg["message_id"] for msg in messages if msg["message_source"] == 0]

    test_cases_map = {}  # 测试集ID → 测试用例列表
    msg_to_suite = {}  # 消息ID → 测试集ID
    # 用于存储消息ID到文件信息的映射
    file_info_map = {}

    # 查询用户消息关联的文件信息
    if user_message_ids:
        files = await FileRecord.filter(message_id__in=user_message_ids) \
            .values("message_id", "file_name", "file_size")

        for file in files:
            # 转换文件大小为友好格式
            formatted_size = format_file_size(float(file["file_size"]))
            file_info_map[file["message_id"]] = {
                "file_name": file["file_name"],
                "file_size": formatted_size
            }

    # 处理AI消息的测试集和测试用例
    if ai_message_ids:
        # 获取关联的测试集
        test_suites = await TestSuite.filter(message_id__in=ai_message_ids) \
            .values("suite_id", "message_id")

        # 构建消息ID到测试集ID的映射
        for suite in test_suites:
            msg_to_suite[suite["message_id"]] = suite["suite_id"]

        suite_ids = list(msg_to_suite.values())

        if suite_ids:
            # 获取测试用例
            test_cases = await TestCase.filter(suite_id__in=suite_ids) \
                .order_by("case_num") \
                .values(
                "feature",
                "case_num",
                "test_scene",
                "preconditions",
                "step",
                "expected",
                "suite_id",
                "case_id"
            )

            # 构建测试集到测试用例的映射
            for case in test_cases:
                suite_id = case["suite_id"]
                if suite_id not in test_cases_map:
                    test_cases_map[suite_id] = []
                test_cases_map[suite_id].append({
                    "feature": case["feature"],
                    "casenum": case["case_num"],
                    "scenario": case["test_scene"],
                    "preconditions": case["preconditions"],
                    "steps": case["step"],
                    "expected": case["expected"],
                    "case_id": case["case_id"],
                    "suite_id": case["suite_id"]
                })

    # 3. 构建最终响应格式
    result = []
    for msg in messages:
        message_data = {
            "content": msg["content"],
            "message_source": msg["message_source"]
        }

        # 用户消息：添加文件信息
        if msg["message_source"] == 0:
            if msg["message_id"] in file_info_map:
                message_data["fileInfo"] = file_info_map[msg["message_id"]]
            else:
                message_data["fileInfo"] = None

        # AI消息：添加测试用例信息
        elif msg["message_source"] == 1:
            # 检查是否有关联的测试集
            if msg["message_id"] in msg_to_suite:
                suite_id = msg_to_suite[msg["message_id"]]
                if suite_id in test_cases_map:
                    message_data["testCases"] = test_cases_map[suite_id]
                else:
                    # 有测试集但没有测试用例
                    message_data["testCases"] = []
            else:
                # 没有关联测试集
                message_data["testCases"] = []

        result.append(message_data)

    return result